package org.ace.logic.login.impl;

import io.netty.channel.Channel;

import javax.annotation.Resource;
import org.ace.logic.login.dto.LoginDTO;
import org.ace.account.IAccountBiz;
import org.ace.endingCode.SocketModel;
import org.ace.logic.AbstractHandlerServImpl;
import org.ace.logic.IHandlerServ;
import org.ace.logic.login.protocol.LoginProtocol;
import org.ace.logic.user.AbstractUserHandlerImpl;
import org.ace.protocol.Protocol;
import org.ace.tool.IExecutorPool;
import org.springframework.stereotype.Service;


public class LoginHandlerServImpl extends AbstractUserHandlerImpl implements
		IHandlerServ {
    //d单线层，底层数据为了保持安全性和一致性，通过单线程约束。网络层的转发，用多先层
	@Resource(name = "executorPool")
	private IExecutorPool executorPool;//操作访问数据库
	//取出事务层
	@Resource(name="accountBiz")
	private IAccountBiz accountBiz;

	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	protected void process(Channel channel, SocketModel message) {
		switch (message.getOpDefinde()) {
		case Protocol.LogionOption:
			login(channel, message);//接受客户端发送消息，发送的消息体，服务端和客户端交流协商
			break;
		case LoginProtocol.CREATE_ACCOUNT_CREQ://创建账号
			createAccount(channel, message);
			break;
		}
	}
	/**
	 * 判断登录，返回消息，登录判断是在事物层写的，这里给客户端发送消息
	 * */
	private void login(final Channel channel,SocketModel<LoginDTO> message){		
	    LoginDTO dto=message.getMessage();
		final String account=dto.account;
		final String passWord=dto.passWord;
		executorPool.execute(new Runnable() {
			//d单线层里调用登录方法，常量，不会有线程安全问题，不会造成数据竞争的问题，可以跨线程传进来
			@Override
			public void run() {
				//继承AbstractUserHandlerImpl 已实现type 的赋值
				write(channel, Protocol.LogionResult, accountBiz.login(channel, account, passWord));				
			}
		});
		//不同的线程，先后不一定
		logger.debug("account:"+dto.account+"    passWord:"+dto.passWord);
	}
	/*
	 * 创建账号
	 */
	private void createAccount(final Channel channel,SocketModel<LoginDTO> message){
		LoginDTO dto=message.getMessage();//如果创建要更多的消息那就要重新定制DTO模型，用于客户端和服务器传输
		final String account=dto.account;
		final String passWord=dto.passWord;
		executorPool.execute(new Runnable() {
			
			@Override
			public void run() {
				write(channel, LoginProtocol.CREATE_ACCOUNT_SRES, accountBiz.create(account, passWord));						
			}
		});
	}
	
	/*
	 * 设置登录模块
	 * */
	public int getType()
	{
		return Protocol.LogionResult;
	}
	
	@Override
	public void Colse(Channel channel) {
		accountBiz.offLine(channel);	
	}

	//登录模块无area ，反不返回无所谓，客服端不对这条协议处理
	@Override
	public int getArea() {
		return 0;
	}
	

}
